#include "stdio.h"
#include "string.h"

//参考学习：
//http://data.biancheng.net/view/5.html


//定义链表节点结构体
struct list_node {

    int val;
    struct list_node *next;
};

static struct list_node *head = NULL;

/******************************************************************************/

//初始化链表
static struct list_node *init_list(void)
{
    //生成头节点
    struct list_node *head = (struct list_node *)malloc(sizeof(struct list_node));
    struct list_node *p = head;

    for (int i = 0; i < 5; i++) {

        struct list_node *tmp = (struct list_node *) malloc(sizeof(struct list_node));
        p->next = tmp;
        tmp->next = NULL;
        tmp->val = i;
        p = p->next;
    }

    return head;
}

//插入一个节点，offs：插入位置， val：插入的值
static struct list_node *insert_list(struct list_node *head, int offs, int val)
{
    int i = 0;
    struct list_node *pre = head;

    //找到插入点的上一个节点
    for (i = 1; i < offs; i++) {
        if (pre == NULL) {  /* 插入点超出了 */
            return head;
        }
        pre = pre->next;
    }

    //创建插入点
    struct list_node *c = (struct list_node *) malloc(sizeof(struct list_node));
    c->val  = val;
    c->next = pre->next;
    pre->next = c;

    return head;
}

//删除一个节点，offs：删除的位置
static struct list_node *delet_list(struct list_node *head, int offs)
{
    struct list_node *pre = head; 
    int i = 0;

    for (i = 1; i < offs; i++) {
        pre = pre->next;
    }

    struct list_node *del = pre->next;
    pre->next = del->next;
    free(del);

    return head;
}

//查找链表
static int select_list(struct list_node *head, int val)
{
    struct list_node *curr = head->next;
    int i = 1;

    while(curr != NULL) {
        if (curr->val == val) {
            return i;
        }
        curr = curr->next;
        i++;
    }

    return -1;
}

//修改指定位置的链表的值, offs:位置  val：需要修改的值
static struct list_node *amend_list(struct list_node *head, int offs, int val)
{
    int i = 0;
    struct list_node *curr = head->next;

    for (i = 1; i < offs; i++) {
        if (curr == NULL) {  /* 替换的节点超出了 */
            return head;
        }
        curr = curr->next;
    }

    curr->val = val;

    return head;
}

//打印链表
static void print_list(struct list_node *head)
{
    struct list_node *curr = head->next;
    while (curr != NULL) {
        printf("%d ", curr->val);
        curr = curr->next;
    }
}

void link_list_test(void)
{
    struct list_node *p;

    printf("\r\ninit_list: \r\n");
    p = init_list();
    head = p;
    print_list(p);
    
    printf("\r\ninsert_list: \r\n");
    p = insert_list(head, 4, 22);
    print_list(p);
    printf("\r\n");
    
    printf("\r\ndelet_list: \r\n");
    p = delet_list(head, 3);
    print_list(p);

    printf("\r\nselect_list: \r\n");
    int ret = select_list(head, 4);
    if (ret != -1) {
        printf("select ok. ret=%d\r\n", ret);
    } else {
        printf("select failed!\r\n");
    }

    printf("\r\namend_list: \r\n");
    amend_list(head, 2, 222);
    print_list(p);

}